package com.neo.tiny.demo.sso.config.security.config;

import com.neo.tiny.demo.sso.config.security.filter.AuthenticationTokenFilter;
import com.neo.tiny.demo.sso.config.security.componse.RestAuthenticationEntryPoint;
import com.neo.tiny.demo.sso.config.security.componse.RestfulAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.annotation.Resource;

/**
 * @Description:
 * @Author: yqz
 * @CreateDate: 2022/11/13 20:07
 */
@Configuration
public class SsoSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Resource
    private AuthenticationTokenFilter authenticationTokenFilter;


    @Autowired
    private RestfulAccessDeniedHandler restfulAccessDeniedHandler;


    @Autowired
    private RestAuthenticationEntryPoint restAuthenticationEntryPoint;


    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        // 设置 URL 安全权限
        httpSecurity.authorizeRequests()
                //可匿名访问
                .antMatchers(
                        "/auth/**",
                        "/*.html",
                        "/**/*.html",
                        "/**/*.js",
                        "/**/*.css",
                        "/**/*.png",
                        "/**/*.ico")
                .permitAll()
                //跨域请求会先进行一次options请求
                .antMatchers(HttpMethod.OPTIONS)
                .permitAll()
                // 除了以上路径，其他都需要验证
                .anyRequest()
                .authenticated();

        // 禁用缓存
        httpSecurity.headers().cacheControl();
        //防止网站攻击：get post
        httpSecurity.csrf().disable()//关闭csrf跨站攻击，登出失败可能的原因
                // 内嵌iframe
                .headers().frameOptions().disable();

        // 设置处理器
        httpSecurity.exceptionHandling()
                .accessDeniedHandler(restfulAccessDeniedHandler)
                .authenticationEntryPoint(restAuthenticationEntryPoint);

        // 添加 Token Filter
        httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
    }

}
